#ifndef DICTIONARY_SECTION_H
#define DICTIONARY_SECTION_H

#include "Types.h"
#include "Sentence.h"

#include <string>
#include <list>
#include <algorithm>
#include <map>

namespace Dictionary {

	template <typename T = std::string>
	class Section {
		public :
			typedef std::map<int, Sentence<T> *> term_place_in_sentence_t; //term place in the sentence maps to sentence
			typedef std::map<int, term_place_in_sentence_t *> sentence_number_t; //sentence number map -> place and sentence

			Section() {}
			Section(SectionType type) : section_type(type) {}
			~Section() 
			{
				std::for_each(sentence_array.begin(),sentence_array.end(),DeleteMapMapContainerContent<sentence_number_t::value_type,term_place_in_sentence_t::value_type >());
			}

			SectionType get_section_type() const { return section_type; }
			long get_term_frequency() const { return term_frequency; }
			const sentence_number_t * get_sentence_array() const { return &sentence_array; }
			const Sentence<T> * get_particular_sentence(int sentence_number, int term_place) const;

			void set_term_frequency(long frequency) { term_frequency = frequency; }
			void add_sentence(Sentence<T> *sentence);
		private :
			SectionType section_type;
			long term_frequency;
			sentence_number_t sentence_array;

			
	};

	/**
	\brief Add sentence to the section The sentence number and term place in the sentence must be set in the sentence before passing it as argument
	**/
	template <typename T>
	void Section<T>::add_sentence(Sentence<T> *sentence)
	{
		int sentence_number = sentence->get_sentence_number();
		int term_place = sentence->get_in_sentence_place();
		sentence_number_t::iterator sentence_number_iter = sentence_array.find(sentence_number);
		term_place_in_sentence_t *term_place_map;
		if (sentence_number_iter == sentence_array.end()) {
			//create new map
			term_place_map = new term_place_in_sentence_t();
			//place term_place and sentence
			term_place_map->insert(term_place_in_sentence_t::value_type(term_place,sentence));
			//place new map in the outer map mapped by sentence_number
			sentence_array.insert(sentence_number_t::value_type(sentence_number,term_place_map));
		}
		else //sentence_number exists
		{
      term_place_map = sentence_number_iter->second;
			term_place_map->insert(term_place_in_sentence_t::value_type(term_place,sentence));
		}
	}

	template <typename T>
	const Sentence<T> * Section<T>::get_particular_sentence(int sentence_number, int term_place) const
	{
    sentence_number_t::const_iterator sentence_number_iter = sentence_array.find(sentence_number);
		if (sentence_number_iter == sentence_array.end()) return NULL;
		term_place_in_sentence_t::const_iterator term_place_iter = sentence_number_iter->second->find(term_place);
		if (term_place_iter == sentence_number_iter->second->end()) return NULL;

		return term_place_iter->second;
	}
}

#endif